package com.sadhoc.router;

import java.io.IOException;
import java.util.Queue;
import java.util.concurrent.ConcurrentLinkedQueue;

import com.sadhoc.router.pdu.HDPacket;
import com.sadhoc.router.util.Debug;
import com.sadhoc.sockets.TCPReceiver;
import com.sadhoc.sockets.UDPReceiver;

public class PacketReceiver implements Runnable {
	
	private UDPReceiver udpReceiver 	= null;
	private TCPReceiver tcpReceiver		= null;
	private Queue<HDPacket> queue 		= null;
	private OnMessageReceiverI recvr 	= null;
	private boolean running 			= true;
	
	/*
	 * Creates UDP and TCP receiver threads
	 */
	public PacketReceiver(String ipAddress, int port, OnMessageReceiverI recvr) throws IOException {
		
		queue = new ConcurrentLinkedQueue<HDPacket>();
		this.recvr = recvr;
				
		udpReceiver = new UDPReceiver(port, this);				
		tcpReceiver = new TCPReceiver(port, this);
				
		Debug.printBasic("PacketReceiver initialized");
	
	}
		
	/*
	 * Executes forever. When a packet is the receivers add to a queue. The queue is processed
	 * here
	 */
	public void run() {

		new Thread(udpReceiver).start();
		new Thread(tcpReceiver).start();
		
		while (running) {
			try {
				
				synchronized(queue) {
					while (queue.isEmpty()) {
						queue.wait();
					}
				}
				
				recvr.onMessageRecv(queue.poll());
				
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}

		stop();
		
	}
	
	/*
	 * Thread safe processing of received TCP messages
	 */
	public void addQueue(HDPacket hdp) {
		
		queue.add(hdp);
		synchronized (queue) {
			queue.notify();
		}
				
	}
		
	/*
	 * Stops the thread
	 */
	public void stop() {
		
		running  = false;
		udpReceiver.stop();
		tcpReceiver.stop();
		
	}
	
}
